import React from 'react';

/**
 * 微应用路由模式
 */
export type RouterMode =
  | 'search'
  | 'native'
  | 'native-scope'
  | 'pure'
  | 'state'
  | 'hash'
  | 'history';

/**
 * 微应用生命周期事件
 */
export interface LifeCycles {
  created?: (event: CustomEvent) => void;
  beforemount?: (event: CustomEvent) => void;
  mounted?: (event: CustomEvent) => void;
  unmount?: (event: CustomEvent) => void;
  error?: (event: CustomEvent) => void;
  beforeshow?: (event: CustomEvent) => void;
  aftershow?: (event: CustomEvent) => void;
  afterhidden?: (event: CustomEvent) => void;
  dataChange?: (event: CustomEvent) => void;
}

/**
 * 微应用配置接口
 */
export interface MicroAppConfig {
  /** 微应用名称 */
  name: string;
  /** 微应用地址 */
  url: string;
  /** 路由模式 */
  routerMode?: RouterMode;
  /** 默认页面 */
  defaultPage?: string;
  /** 是否保持活跃 */
  keepAlive?: boolean;
  /** 是否使用iframe */
  iframe?: boolean;
  /** 是否内联模式 */
  inline?: boolean;
  /** 是否禁用样式隔离 */
  disableScopecss?: boolean;
  /** 是否禁用沙箱 */
  disableSandbox?: boolean;
  /** 是否禁用虚拟路由系统 */
  disableMemoryRouter?: boolean;
  /** 是否保持路由状态 */
  keepRouterState?: boolean;
  /** 是否禁用请求劫持 */
  disablePatchRequest?: boolean;
  /** 是否销毁 */
  destroy?: boolean;
  /** 是否开启fiber模式 */
  fiber?: boolean;
  /** 基础路由 */
  baseroute?: string;
  /** 是否开启ssr */
  ssr?: boolean;
  /** 传递给微应用的数据 */
  data?: any;
  /** 生命周期事件 */
  lifeCycles?: LifeCycles;
}

/**
 * 微应用组件基础属性
 */
export interface MicroAppComponentProps extends MicroAppConfig {
  // 官方事件 - 完全透传
  onCreated?: (event: CustomEvent) => void;
  onBeforemount?: (event: CustomEvent) => void;
  onMounted?: (event: CustomEvent) => void;
  onUnmount?: (event: CustomEvent) => void;
  onError?: (event: CustomEvent) => void;
  onBeforeshow?: (event: CustomEvent) => void;
  onAftershow?: (event: CustomEvent) => void;
  onAfterhidden?: (event: CustomEvent) => void;
  onDataChange?: (event: CustomEvent) => void;

  // 扩展属性
  /** 加载状态或自定义加载组件 */
  loading?: boolean | React.ReactNode;
  /** 是否启用错误边界 */
  errorBoundary?: boolean;
  /** 是否自动重试 */
  autoRetry?: boolean;
  /** 重试次数 */
  retryCount?: number;
  /** 重试延迟 */
  retryDelay?: number;
  /** 重试回调 */
  onRetry?: () => void;
  /** 自定义类名 */
  className?: string;
  /** 自定义样式 */
  style?: React.CSSProperties;
}

/**
 * BasicMicroApp 组件属性
 */
export type BasicMicroAppProps = MicroAppComponentProps;

/**
 * MicroPortalWeb 组件属性
 */
export interface MicroPortalWebProps extends BasicMicroAppProps {
  /** 是否显示进度条 */
  showProgress?: boolean;
  /** 进度条颜色 */
  progressColor?: string;
  /** 进度条高度 */
  progressHeight?: number;
  /** NProgress 配置选项 */
  progressOptions?: any;
  /** 是否可见 */
  visible?: boolean;
}

/**
 * MicroBizWidget 组件属性
 */
export interface MicroBizWidgetProps extends BasicMicroAppProps {
  /** 宽度 */
  width?: number | string;
  /** 高度 */
  height?: number | string;
  /** 最小宽度 */
  minWidth?: number | string;
  /** 最小高度 */
  minHeight?: number | string;
  /** 最大宽度 */
  maxWidth?: number | string;
  /** 最大高度 */
  maxHeight?: number | string;
  /** 是否可调整大小 */
  resizable?: boolean;
  /** 尺寸变化回调 */
  onResize?: (width: number, height: number) => void;
}

/**
 * EnhancedMicroApp 组件属性
 */
export interface EnhancedMicroAppProps extends BasicMicroAppProps {
  /** 是否显示遮罩加载 */
  maskLoading?: boolean;
  /** 加载文本 */
  loadingText?: string;
  /** 加载图标 */
  loadingIcon?: React.ReactNode;
  /** 是否启用触摸 */
  touchEnabled?: boolean;
  /** 触摸开始事件 */
  onTouchStart?: (event: TouchEvent) => void;
  /** 触摸结束事件 */
  onTouchEnd?: (event: TouchEvent) => void;
  /** 是否显示遮罩 */
  showMask?: boolean;
  /** 自定义加载渲染函数 */
  customLoadingRenderer?: (
    children: React.ReactNode,
    props: any,
    isLoading: boolean,
  ) => React.ReactNode;
  /** 生命周期事件 */
  lifeCycleEvents?: {
    onCreated?: () => void;
    onBeforemount?: () => void;
    onMounted?: () => void;
    onUnmount?: () => void;
    onError?: (error: any) => void;
    onAfterhidden?: () => void;
    onAftershown?: () => void;
  };
}

/**
 * 错误回退组件属性
 */
export interface ErrorFallbackProps {
  error: Error;
  resetError: () => void;
  retry: () => void;
}

/**
 * MicroAppErrorBoundary 组件属性
 */
export interface MicroAppErrorBoundaryProps {
  /** 子组件 */
  children: React.ReactNode;
  /** 错误回退组件 */
  fallback?: React.ComponentType<ErrorFallbackProps>;
  /** 错误回调 */
  onError?: (error: Error, errorInfo: React.ErrorInfo) => void;
  /** 重试回调 */
  onRetry?: () => void;
  /** 是否自动重试 */
  autoRetry?: boolean;
  /** 重试次数 */
  retryCount?: number;
  /** 重试延迟 */
  retryDelay?: number;
  /** 是否显示Toast */
  showToast?: boolean;
  /** Toast消息 */
  toastMessage?: string;
}

/**
 * MaskLoading 组件属性
 */
export interface MaskLoadingProps {
  /** 是否显示加载状态 */
  visible?: boolean;
  /** 子组件 */
  children?: React.ReactNode;
  /** 自定义类名 */
  className?: string;
  /** 自定义样式 */
  style?: React.CSSProperties;
  /** 加载文本 */
  loadingText?: string;
  /** 加载图标 */
  loadingIcon?: React.ReactNode;
}

/**
 * 组件引用接口
 */
export interface MicroAppRef {
  /** 重新加载微应用 */
  reload: () => void;
  /** 设置加载状态 */
  setLoading?: (loading: boolean) => void;
  /** 获取调试信息 */
  getDebugInfo?: () => any;
}

/**
 * 通信消息接口
 */
export interface CommunicationMessage {
  /** 消息类型 */
  type: string;
  /** 消息数据 */
  data: any;
  /** 时间戳 */
  timestamp: number;
  /** 来源应用 */
  source: string;
  /** 目标应用 */
  target?: string;
}

/**
 * 通信配置接口
 */
export interface CommunicationConfig {
  /** 应用名称 */
  appName: string;
  /** 应用类型 */
  appType: 'main' | 'sub';
  /** 是否启用全局数据 */
  enableGlobalData?: boolean;
  /** 是否启用子应用间通信 */
  enableSubAppCommunication?: boolean;
}

/**
 * 主应用通信接口
 */
export interface MainAppCommunication {
  /** 发送数据到子应用 */
  sendToSubApp: (appName: string, data: any) => void;
  /** 广播数据到所有子应用 */
  broadcastToAllSubApps: (data: any) => void;
  /** 监听来自子应用的数据 */
  onDataFromSubApp: (
    appName: string,
    callback: (data: any) => void,
  ) => () => void;
}

/**
 * 子应用通信接口
 */
export interface SubAppCommunication {
  /** 发送数据到主应用 */
  sendToMain: (data: any) => void;
  /** 发送数据到其他子应用 */
  sendToSubApp: (targetAppName: string, data: any) => void;
  /** 监听来自主应用的数据 */
  onDataFromMain: (callback: (data: any) => void) => () => void;
  /** 监听来自其他子应用的数据 */
  onDataFromSubApp: (
    targetAppName: string,
    callback: (data: any) => void,
  ) => () => void;
}

/**
 * 通信事件回调
 */
export type CommunicationCallback = (data: any) => void;

/**
 * 通信事件清理函数
 */
export type CommunicationCleanup = () => void;

/**
 * useMicroApp Hook 配置选项
 */
export interface UseMicroAppOptions {
  /** 微应用名称 */
  name: string;
  /** 微应用地址 */
  url: string;
  /** 是否自动挂载 */
  autoMount?: boolean;
  /** 挂载完成回调 */
  onMounted?: () => void;
  /** 卸载完成回调 */
  onUnmounted?: () => void;
  /** 错误回调 */
  onError?: (error: Error) => void;
}

/**
 * useMicroApp Hook 返回值
 */
export interface UseMicroAppReturn {
  // 应用状态
  /** 是否已加载 */
  isLoaded: boolean;
  /** 是否发生错误 */
  isError: boolean;
  /** 是否正在加载 */
  isLoading: boolean;

  // 应用操作
  /** 重新加载应用 */
  reload: () => void;
  /** 卸载应用 */
  unmount: () => void;

  // 数据操作
  /** 设置数据 */
  setData: (data: any) => void;
  /** 获取数据 */
  getData: () => any;

  // 事件监听
  /** 监听数据变化 */
  onDataChange: (callback: (data: any) => void) => CommunicationCleanup;
}

/**
 * useMicroAppCommunication Hook 配置选项
 */
export type UseMicroAppCommunicationOptions = CommunicationConfig;

/**
 * useMicroAppCommunication Hook 返回值
 */
export interface UseMicroAppCommunicationReturn {
  // 发送数据
  /** 发送数据到主应用 */
  sendToMain: (data: any) => void;
  /** 发送数据到子应用 */
  sendToSubApp: (appName: string, data: any) => void;
  /** 广播数据 */
  broadcast: (data: any) => void;

  // 接收数据
  /** 监听来自主应用的数据 */
  onDataFromMain: (callback: CommunicationCallback) => CommunicationCleanup;
  /** 监听来自子应用的数据 */
  onDataFromSubApp: (
    appName: string,
    callback: CommunicationCallback,
  ) => CommunicationCleanup;

  // 全局数据
  /** 设置全局数据 */
  setGlobalData: (data: any) => void;
  /** 获取全局数据 */
  getGlobalData: () => any;
}

/**
 * useMicroAppError Hook 配置选项
 */
export interface UseMicroAppErrorOptions {
  /** 是否自动重试 */
  autoRetry?: boolean;
  /** 重试次数 */
  retryCount?: number;
  /** 重试延迟 */
  retryDelay?: number;
  /** 错误回调 */
  onError?: (error: Error) => void;
  /** 重试回调 */
  onRetry?: () => void;
}

/**
 * useMicroAppError Hook 返回值
 */
export interface UseMicroAppErrorReturn {
  // 错误状态
  /** 是否有错误 */
  hasError: boolean;
  /** 错误对象 */
  error: Error | null;

  // 错误处理
  /** 重试 */
  retry: () => void;
  /** 清除错误 */
  clearError: () => void;

  // 错误监听
  /** 监听错误 */
  onError: (callback: (error: Error) => void) => CommunicationCleanup;
}

// micro-app 类型声明
declare module '@micro-zoe/micro-app' {
  interface MicroAppConfig {
    name: string;
    url: string;
    [key: string]: any;
  }

  interface MicroAppInstance {
    reload(name: string, destroy?: boolean): void;
    unmountApp?(name: string, destroy?: boolean): void;
    setData(name: string, data: any, callback?: (res: any) => void): void;
    getData(name: string): any;
    setGlobalData?(data: any): void;
    getGlobalData?(): any;
    addDataListener(name: string, listener: (data: any) => void): void;
    removeDataListener(name: string, listener: (data: any) => void): void;
    addGlobalDataListener?(listener: (data: any) => void): void;
    removeGlobalDataListener?(listener: (data: any) => void): void;
    getActiveApps?(): string[];
    preFetch?(apps: Array<{ name: string; url: string }>): void;
  }

  const microApp: MicroAppInstance;
}

declare module '@micro-zoe/micro-app/polyfill/jsx-custom-event' {
  const jsxCustomEvent: any;
}

// nprogress 类型声明已由 @types/nprogress 提供

// 全局JSX类型扩展
declare global {
  // eslint-disable-next-line @typescript-eslint/no-namespace
  namespace JSX {
    interface IntrinsicElements {
      'micro-app': {
        name?: string;
        url?: string;
        'router-mode'?: string;
        'default-page'?: string;
        'keep-alive'?: boolean;
        iframe?: boolean;
        inline?: boolean;
        'disable-scopecss'?: boolean;
        'disable-sandbox'?: boolean;
        'disable-memory-router'?: boolean;
        'keep-router-state'?: boolean;
        'disable-patch-request'?: boolean;
        destroy?: boolean;
        fiber?: boolean;
        baseroute?: string;
        ssr?: boolean;
        data?: any;
        className?: string;
        style?: React.CSSProperties;
        ref?: React.Ref<any>;

        // 事件处理
        onCreated?: (event: CustomEvent) => void;
        onBeforemount?: (event: CustomEvent) => void;
        onMounted?: (event: CustomEvent) => void;
        onUnmount?: (event: CustomEvent) => void;
        onError?: (event: CustomEvent) => void;
        onBeforeshow?: (event: CustomEvent) => void;
        onAftershow?: (event: CustomEvent) => void;
        onAfterhidden?: (event: CustomEvent) => void;
        onDataChange?: (event: CustomEvent) => void;

        [key: string]: any;
      };
    }
  }
}
